home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et-2_2.lha / et2.2 / src / Cluster.C < prev    next >
C/C++ Source or Header  |  1990-12-04  |  4KB  |  233 lines

  1. //$Cluster$
  2. #include "Cluster.h"
  3. #include "Math.h"
  4. #include "Storage.h"
  5.  
  6. //---- Cluster -----------------------------------------------------------------
  7.  
  8. MetaImpl(Cluster, (T(rows), T(cols), T(minGap), T(actGap), 
  9.            T(minsize), TE(align),0));
  10.  
  11. Cluster::Cluster(int id, VObjAlign a, Point g, Collection *cp)
  12.                     : CompositeVObject(id, cp)
  13. {
  14.     Init(a, g);
  15. }
  16.  
  17. Cluster::Cluster(int id, VObjAlign a, Point g, VObject *va_(vop), ...)
  18.                     : CompositeVObject(id, (Collection*)0)
  19. {
  20.     va_list ap;
  21.     va_start(ap, va_(vop));
  22.     Add(va_(vop));
  23.     SetItems(ap);
  24.     Init(a, g);
  25.     va_end(ap);
  26. }
  27.  
  28. Cluster::Cluster(int id, VObjAlign a, Point g, va_list ap)
  29.                     : CompositeVObject(id, ap)
  30. {
  31.     Init(a, g);
  32. }
  33.  
  34. Cluster::~Cluster()
  35. {
  36.     SafeDelete(wd);
  37.     SafeDelete(ht);
  38.     SafeDelete(bs);
  39. }
  40.  
  41. void Cluster::Init(VObjAlign a, Point g)
  42. {
  43.     minGap= actGap= g;
  44.     align= a;
  45.     rows= cols= 0;
  46.     wd= ht= bs= 0;
  47.     CalcDimensions();
  48. }
  49.  
  50. void Cluster::CalcDimensions()
  51. {
  52.     int x, y, s= Size();
  53.     
  54.     if (s > 0) {
  55.     x= CalcCols();
  56.     y= (s-1)/x+1;
  57.     
  58.     if (rows != y) {
  59.         rows= y;
  60.         ht= (short*) Realloc(ht, rows * sizeof(short));
  61.         bs= (short*) Realloc(bs, rows * sizeof(short));
  62.     }
  63.     if (cols != x) {
  64.         cols= x;
  65.         wd= (short*) Realloc(wd, cols * sizeof(short));
  66.     }
  67.     modified= FALSE;
  68.     } else
  69.     rows= cols= 0;
  70.     CacheMinSize();
  71. }
  72.  
  73. short Cluster::CalcCols()
  74. {
  75.     int x, s= Size();
  76.     register VObjAlign aa;
  77.     
  78.     aa= (VObjAlign)(align & ~(eVObjHExpand|eVObjVExpand));
  79.     if ((aa & eVObjH) && (aa & eVObjV))
  80.     x= intsqrt(s);
  81.     else if (aa & eVObjH)
  82.     x= 1;
  83.     else if (aa & eVObjV)
  84.     x= s;
  85.     else
  86.     x= 1; // tom@iyf.tno.nl
  87.     return x;
  88. }
  89.  
  90. void Cluster::SetOrigin(Point at)
  91. {
  92.     register VObject *dip;
  93.     register int x, y;
  94.     Point a;
  95.     
  96.     VObject::SetOrigin(at);
  97.     
  98.     a.x= at.x;
  99.     for (x= 0; x < cols; x++) {
  100.     a.y= at.y;
  101.     for (y= 0; y < rows; y++) {
  102.         if (dip= GetItem(x,y))
  103.         dip->Align(a, Metric(wd[x], ht[y], bs[y]), align);
  104.         a.y+= ht[y] + actGap.y;
  105.     }
  106.     a.x+= wd[x] + actGap.x;
  107.     }
  108. }
  109.  
  110. Metric Cluster::GetMinSize()
  111. {
  112.     if (modified)
  113.     CalcDimensions();
  114.     return minsize;
  115. }
  116.  
  117. int Cluster::Base()
  118. {
  119.     return minsize.Base();
  120. }
  121.  
  122. void Cluster::CacheMinSize()
  123. {
  124.     Metric m;
  125.     
  126. //    if (Size() > 0) {
  127.     register VObject *dip;
  128.     register int x, y, hh, bb;
  129.     int totalw, totalh, totalb, mid;
  130.     
  131.     mid= rows/2;
  132.     if (EVEN(rows))
  133.         mid--;
  134.         
  135.     totalb= totalh= totalw= 0;
  136.     for (y= 0; y < rows; y++) {
  137.         hh= bb= 0;
  138.         for (x= 0; x < cols; x++) {
  139.         if (dip= GetItem(x, y)) {
  140.             m= dip->GetMinSize();
  141.             if (align & eVObjVBase) {
  142.             hh= max(hh, m.Base());
  143.             int eb= m.Height()-m.Base();
  144.             bb= max(bb, eb);
  145.             } else
  146.             hh= max(hh, m.Height());
  147.             if (y == 0)
  148.             wd[x]= m.Width();
  149.             else
  150.             wd[x]= max(wd[x], m.Width());
  151.         }
  152.         }
  153.         if (y == mid) {
  154.         totalb= totalh+hh;
  155.         if (EVEN(rows))
  156.             totalb+= bb;
  157.         }
  158.         ht[y]= hh+bb;
  159.         bs[y]= hh;
  160.         totalh+= ht[y];
  161.     }
  162.     for (x= 0; x < cols; x++)
  163.         totalw+= wd[x];
  164.         
  165.     m.extent.x= totalw + minGap.x*(cols-1);
  166.     m.extent.y= totalh + minGap.y*(rows-1);
  167.     m.base= totalb + minGap.y * mid;
  168. //    }
  169.     
  170.     minsize= m;
  171. }
  172.  
  173. void Cluster::SetExtent(Point e)
  174. {   
  175.     register VObject *dip;
  176.     register int x, y, divx= 0, divy= 0, b;
  177.     Metric m;
  178.     bool hexp= (align & eVObjHExpand),
  179.      vexp= (align & eVObjVExpand);
  180.     
  181.     Point d= e-minsize.Extent();
  182.     
  183.     VObject::SetExtent(e);
  184.     
  185.     actGap= minGap;
  186.     if (hexp)
  187.     divx= d.x/cols;
  188.     else if (cols > 1)
  189.     divx= d.x/(cols-1);
  190.     else
  191.     divx= 0;
  192.     if (vexp)
  193.     divy= d.y/rows;
  194.     else if (rows > 1)
  195.     divy= d.y/(rows-1);
  196.     else
  197.     divy= 0;
  198.     actGap.x+= divx;
  199.     actGap.y+= divy;
  200.     
  201.     for (x= 0; x < cols; x++) {
  202.     for (y= 0; y < rows; y++) {
  203.         if (dip= GetItem(x, y)) {
  204.         m= dip->GetMinSize();
  205.         if (hexp)
  206.             m.extent.x= wd[x] + divx;
  207.         if (vexp)
  208.             m.extent.y= ht[y] + divy;
  209.         if (m.Extent() != dip->GetExtent())
  210.             dip->SetExtent(m.Extent());
  211.         }
  212.     }
  213.     }
  214.     b= rows/2;
  215.     if (EVEN(rows))
  216.     b--;
  217.     minsize.base+= b * divy;
  218. }
  219.  
  220. ostream& Cluster::PrintOn(ostream &s)
  221. {
  222.     CompositeVObject::PrintOn(s);
  223.     return s << minGap SP << align SP;
  224. }
  225.  
  226. istream& Cluster::ReadFrom(istream &s)
  227. {
  228.     CompositeVObject::ReadFrom(s);
  229.     s >> minGap >> Enum(align);
  230.     actGap= minGap;
  231.     return s;
  232. }
  233.